package com.wolfking.jeesite.controller;

import com.google.common.collect.Lists;
import com.wolfking.jeesite.config.SsoConfig;
import com.wolfking.jeesite.entity.Menu;
import com.wolfking.jeesite.entity.User;
import com.wolfking.jeesite.freemarker.TemplateRenderService;
import com.wolfking.jeesite.service.MenuService;
import com.wolfking.jeesite.sign.LoginUser;
import com.wolfking.jeesite.sign.Sign;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;


/**
 * 菜单的controller
 * <p>
 *
 * @author wolfking@赵伟伟
 * @mail zww199009@163.com
 * @创作日期 2017年5月2日上午11:36:02
 * @版权 归wolfking所有
 */
@Slf4j
@Controller
@RequestMapping("/sys/menu")
public class MenuController {
    @Autowired
    private MenuService menuService;

    @Autowired
    private SsoConfig ssoConfig;

    @Autowired
    private TemplateRenderService templateRenderService;

    @Sign(code = "sys:menu:view")
    @RequestMapping(value = "/list", method = {RequestMethod.GET, RequestMethod.POST})
    public String list(Model model) {
        List<Menu> sourcelist = menuService.list().stream()
                .sorted(Comparator.comparingInt(Menu::getSort))
                .collect(Collectors.toList());
        List<Menu> list = Lists.newArrayList();
        sortList(list, sourcelist, 1, true);
        model.addAttribute("list", list);
        return "sys/menu/list";
    }

    /**
     * 字典的编辑页面
     *
     * @param model
     * @param menu
     * @return
     */
    @Sign(code = "sys:menu:view")
    @RequestMapping(value = "/edit", method = RequestMethod.GET)
    public String edit(Model model, Menu menu) {
        if (Objects.nonNull(menu.getId()))
            menu = menuService.getById(menu.getId());
        model.addAttribute("menu", menu);
        List<Menu> list = menuService.list();
        model.addAttribute("list", list);
        return "sys/menu/edit";
    }

    /**
     * 字典的保存或者修改
     *
     * @param menu
     * @return
     */
    @Sign(code = "sys:menu:edit")
    @RequestMapping(value = "/edit", method = RequestMethod.POST)
    public String edits(Menu menu, RedirectAttributes redirectAttributes) {
        if (Objects.nonNull(menu.getId())) {
            menuService.updateById(menu);
            redirectAttributes.addFlashAttribute("message", "修改菜单成功");
        } else {
            menuService.save(menu);
            redirectAttributes.addFlashAttribute("message", "添加菜单成功");
        }
        return ssoConfig.getRedirectWithPath("/sys/menu/list");
    }

    /**
     * 菜单的保存或者修改
     *
     * @param menu
     * @return
     */
    @Sign(code = "sys:menu:view")
    @RequestMapping(value = "/copyEdit", method = RequestMethod.GET)
    public String copyEdit(Model model, Menu menu) {
        if (Objects.nonNull(menu.getId())) {
            menu = menuService.getById(menu.getId());
            if(Objects.isNull(menu)){
                menu = new Menu();
            }else {
                menu.setName(menu.getName() + "-2");
                if (Objects.nonNull(menu.getSort())) {
                    menu.setSort(menu.getSort() + 1);
                } else {
                    menu.setSort(1);
                }
                if (StringUtils.isNotBlank(menu.getRemarks())) {
                    menu.setRemarks(menu.getRemarks() + "-2");
                } else {
                    menu.setRemarks(menu.getName());
                }
                menu.setId(null);
                menu.setCreateTime(null);
                menu.setUpdateTime(null);
                menu.setVersion(0);
            }
        }
        model.addAttribute("menu", menu);
        List<Menu> list = menuService.list();
        model.addAttribute("list", list);
        return "sys/menu/edit";
    }


    /**
     * 删除字典值
     *
     * @param id
     * @return
     */
    @Sign(code = "sys:menu:edit")
    @RequestMapping(value = "/delete", method = RequestMethod.GET)
    public String delete(@RequestParam Integer id) {
        if (Objects.nonNull(id))
            menuService.deleteById(id);
        return ssoConfig.getRedirectWithPath("/sys/menu/list");
    }

    private void sortList(List<Menu> list, List<Menu> sourceList, Integer parentId, boolean cascade) {
        for (int i = 0; i < sourceList.size(); i++) {
            Menu e = sourceList.get(i);
            if (parentId.equals(e.getParentId())) {
                list.add(e);
                if (cascade) {
                    // 判断是否还有子节点, 有则继续获取子节点
                    for (int j = 0; j < sourceList.size(); j++) {
                        Menu child = sourceList.get(j);
                        if (e.getId().equals(child.getParentId())) {
                            sortList(list, sourceList, e.getId(), true);
                            break;
                        }
                    }
                }
            }
        }
    }


    @Sign
    @RequestMapping(value = "/tree")
    public String tree(Model model, @LoginUser User user, @RequestParam(value = "parentId", defaultValue = "1") Integer parentId) {
        List<Menu> menuList = menuService.getUserMenus(user.getId()).stream().peek(m -> {
            if (StringUtils.isBlank(m.getTarget())) {
                m.setTarget("mainFrame");
            }
            if (StringUtils.isBlank(m.getIcon())) {
                m.setIcon("circle-arrow-right");
            }
        }).collect(Collectors.toList());
        List<Menu> list = Lists.newArrayList();
        sortList(list, menuList, parentId, true);
        model.addAttribute("menuList", assemblyMenuUrl(list));
        model.addAttribute("parentId", parentId);
        return "sys/menu/menuTree";
    }

    private List<Menu> assemblyMenuUrl(List<Menu> menus) {
        return menus.stream().peek(menu -> {
            if (StringUtils.isNotBlank(menu.getHref())) {
                menu.setHref(templateRenderService.renderTemplate(menu.getHref()));
            }
        }).collect(Collectors.toList());
    }

    @Sign(code = "sys:menu:edit")
    @RequestMapping(value = "/updateSort")
    public String updateSort(String[] ids, String[] sorts, RedirectAttributes redirectAttributes) {
        for (int i = 0; i < ids.length; i++) {
            Menu menu = new Menu();
            menu.setId(Integer.parseInt(ids[i].replace(",", "")));
            menu.setSort(Integer.parseInt(sorts[i].replace(",", "")));
            menuService.updateMenuSort(menu);
        }
        redirectAttributes.addFlashAttribute("message", "保存菜单排序成功");
        return ssoConfig.getRedirectWithPath("/sys/menu/list");
    }
}
